import fs = require('fs');
import { Voice } from '../common/voice';
import { LoggerUtility } from '../logger/logger.utility';
import { ArrayUtils } from '../utility/array.utility';
import { DateUtils } from '../utility/date.utility';
import {
    ActionFeedbackMap, Support2LevelDomain, SupportActionMap,
    SupportFrontendOrder, SupportIntent, SupportNMap,
} from './test.const';

export class TestHandler {
    public voice = new Voice();
    public actions: string[] = [
        '返回', '关闭', '闲聊', '追问',
        '公司基本信息', '公司运营情况', '行业指数', '产品检测', '物流信息', '项目信息', '供应商信息', '视频',
    ];
    public async readPCM(): Promise<{ flag: boolean, output: any }> {
        try {
            // const response = await this.voice.RecognizeLocalFile('D:/Project/Lab/test-voice/assets/pcm/16k.wav');
            // const words = await this.voice.wordAnalysisCustom(response.result[0]);
            const words = await this.voice.wordAnalysisCustom('你好, hello,再见 ,天气,吃,早上好,下午好,晚上好,睡觉,在心里');
            const result = this.semanticComprehension(words.items);
            return { flag: true, output: result };
        } catch (error) {
            return { flag: false, output: 'voice error:' + error };
        }
    }

    public async readRemote(): Promise<{ flag: boolean, output: any }> {
        try {
            const result = await this.voice.RecognizeOnline('http://bos.nj.bpc.baidu.com/v1/audio/8k.amr');
            return { flag: true, output: result };
        } catch (error) {
            return { flag: false, output: 'voice error:' + error };
        }
    }

    public async convertAudio(): Promise<{ flag: boolean, output: any }> {
        try {
            const result = await this.voice.text2Audio('测试测试，你好。');
            fs.writeFileSync('D:/Project/Lab/test-voice/assets/pcm/合成.mp3', result.data);
            return { flag: true, output: 'compose success' };
        } catch (error) {
            return { flag: false, output: 'voice error:' + error };
        }
    }

    private semanticComprehension(words: any[]): { order: string, voice: string, data: any[] } {
        try {
            let order = '';
            let voice = '';
            const data = [];  // TODO 数据处理
            const timeWords = words.filter((x) => x.ne === 'TIME');
            const nounWords = words.filter((x) => x.pos === 'n' || x.pos === 'vn');
            const actionWords = words.filter((x) => x.pos === 'v');
            const actionKeys = actionWords.map((x) => x.item);
            const intent = this.intentAnalysis(actionKeys);
            const timeAnalysis = this.timeAnalysis(timeWords);
            const result = this.nounAnalysis(nounWords);
            // 1. 找到明确行动 obvious action
            if (result.noun.length === 1) {
                order = SupportFrontendOrder.get(result.noun[0]);
                voice = '已收到指令';
                // data.push();
            } else if (result.noun.length > 1) {  // 2. 确认多种行动 multi-action
                order = '追问';
                voice = '您是想知道';
                for (let index = 0; index < result.noun.length; index++) {
                    if (index === result.noun.length - 1) {
                        voice += result.noun[index];
                    } else {
                        voice += result.noun[index] + ', 还是';
                    }
                }
            } else {
                // 3. 没找到明确行动 - 闲聊
                if (intent === SupportIntent.Interest) {
                    order = '闲聊';
                    voice = this.usualAnalysis(words);
                } else {
                    // 4. 没找到明确行动 - 确认意图
                    order = '追问';
                    voice = '我们现在能提供公司信息、运营情况、项目信息、行业指数、产品检测合格率、供应商信息、物流信息、视频监控等数据可查询';
                }
            }
            return { order, voice, data };
        } catch (error) {
            // 错误处理
            LoggerUtility.error('semanticComprehension exception', error);
            let errorHandler;
            if (error.message.indexOf('DateError') > -1) {
                errorHandler = '我没理解您说的时间, 请用某年某月某日到某年某月某日说明';
            } else {
                errorHandler = '抱歉，我没理解您的意思, 请试着再对我说一次';
            }
            return { order: undefined, voice: errorHandler, data: [] };
        }
    }

    private intentAnalysis(actions: any[]): number {
        const intents = [];
        actions.forEach((element) => {
            if (SupportActionMap.get(element)) {
                intents.push(SupportActionMap.get(element));
            }
        });
        if (intents.length === 0) {
            return SupportIntent.Query;
        } else {
            const result = ArrayUtils.findSimilarTerms(intents);
            return ArrayUtils.findSimilarTerms(intents).max;
        }
    }

    private timeAnalysis(times: any[]): string[] {
        const result = [];
        times.map((x) => {
            result.push(DateUtils.convertFromCN(x.item));
        });
        return DateUtils.dateOrderBy(result);
    }

    private nounAnalysis(nouns: any[]): { domain: number, noun: string[] } {
        const result = [];
        nouns.forEach((element) => {
            if (SupportNMap.get(element.item) && !result.includes(SupportNMap.get(element.item))) {
                result.push(SupportNMap.get(element.item));
            }
        });
        if (result.length === 0) {
            return { domain: 0, noun: [] };
        } else if (result.length >= 2) {
            return { domain: 0, noun: result };
        } else {
            const domain = Support2LevelDomain.get(result[0]);
            return { domain, noun: result };
        }
    }

    private usualAnalysis(words: any[]): string {
        let result: string = '';
        words.forEach((element) => {
            if (ActionFeedbackMap.get(element.item)) {
                result = ActionFeedbackMap.get(element.item);
            }
        });
        return result === '' ? '抱歉，我没理解您的意思, 请试着再对我说一次' : result;
    }
}
